package CouponService

import (
	"context"
	"errors"
	"gdshop-font-api-go/app/entity"
	"gdshop-font-api-go/app/request/CouponReq"
	"gdshop-font-api-go/library/response"
	toolsDb "gdshop-font-api-go/library/tools/db"
	"github.com/gogf/gf/database/gdb"
	"github.com/gogf/gf/frame/g"
	"time"
)

func Receive(ctx context.Context, parames *CouponReq.Receive) *response.JsonResponse {
	var cModel *entity.Coupon
	err := toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "coupon").Where(
		"id", parames.Id).Struct(&cModel)
	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}
	if cModel == nil {
		return response.FailByRequestMessage(nil, "找不到优惠券")
	}

	nowTime := int(time.Now().Unix())
	// 判断领取时间
	if cModel.ReceiveTimeType == 1 {
		if cModel.ReceiveTimeStart > nowTime {
			return response.FailByRequestMessage(nil, "未到领取时间")
		}
		if cModel.ReceiveTimeEnd < nowTime {
			return response.FailByRequestMessage(nil, "优惠券过期了")
		}
	}
	// 判断优惠券最后使用时间 time_type = 1 time_end
	if cModel.TimeType == 1 {
		if cModel.TimeEnd < nowTime {
			return response.FailByRequestMessage(nil, "优惠券过期了")
		}
	}
	// 判断是否 超出领取限制 receive_limit
	count, err := toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "member_coupon").Where(
		"coupon_id = ? AND member_id = ?", parames.Id, parames.MemberId,
	).Fields("1").Count()
	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}
	if count > cModel.ReceiveLimit {
		return response.FailByRequestMessage(nil, "达到领取限制")
	}
	// 判断领取数超过发放总数
	count, err = toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "member_coupon").Where(
		"coupon_id = ?", parames.Id,
	).Fields("1").Count()
	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}
	if (count + 1) > cModel.QuantityIssued {
		return response.FailByRequestMessage(nil, "优惠券领完了")
	}
	var id int64
	err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		insert, err := tx.Ctx(ctx).Model("member_coupon").Unscoped().Insert(g.Map{
			"member_id":    parames.MemberId,
			"coupon_id":    parames.Id,
			"receive_time": nowTime,
			"expires_time": getExpiresTime(cModel), // 过期时间
			"delete_at":    1,                      // 先设置为1，后面使用条件更新
		})
		if err != nil {
			return err
		}
		id, err = insert.LastInsertId()
		if err != nil {
			return err
		}
		if id < 1 {
			return errors.New("领取失败")
		}
		update, err := tx.Ctx(ctx).Model("member_coupon").Unscoped().Where(
			"id = ? AND delete_at = 1 AND "+
				"(SELECT quantity_issued FROM gd_coupon c WHERE c.id=?) "+
				"> (SELECT c FROM (SELECT COUNT(1) AS c FROM gd_member_coupon cc WHERE cc.coupon_id ="+
				"? AND cc.delete_at =0) aa)",
			id, parames.Id, parames.Id).Update(g.Map{
			"delete_at": 0,
		})
		if err != nil {
			return err
		}
		affected, err := update.RowsAffected()
		if err != nil {
			return err
		}

		if affected < 1 {
			return errors.New("领取失败")
		}

		return nil
	})
	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}

	return response.SuccessByRequestMessageData(nil, "领取成功", g.Map{
		"id": id,
	})
}

func getExpiresTime(cModel *entity.Coupon) int {
	switch cModel.TimeType {
	case 2:
		return int(time.Now().Unix()) + cModel.TimeDays*86400
	case 1:
		return cModel.TimeEnd
	}
	return int(time.Now().Unix())
}
